package com.xique.park.mapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xique.park.bean.domain.ParkStatisticsIncome;
import com.xique.park.bean.domain.PayOrder;
import com.xique.park.bean.dto.PayOrderDto;
import com.xique.park.bean.dto.PayOrderExportIcbcDto;
import com.xique.park.bean.request.web.payorder.PayOrderRequest;
import com.xique.park.bean.vo.web.payOrder.PayOrderVo;
import org.apache.ibatis.annotations.Param;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 支付记录Mapper接口
 *
 * @author ww
 * @date 2021-12-22
 */
public interface PayOrderMapper extends RootMapper<PayOrder> {

    /**
     * 查询今天的订单数量和订单收入
     *
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param deptId     服务商ID
     * @param parkInfoId 项目ID
     * @return 订单统计数据
     */
    PayOrderDto selectParkingOrderByToday(@Param("province") Integer province,
                                          @Param("city") Integer city,
                                          @Param("district") Integer district,
                                          @Param("deptId") Long deptId,
                                          @Param("parkInfoId") Long parkInfoId);

    /**
     * 按年月统计停车场总收入
     *
     * @param year          年
     * @param month         月
     * @param parkId        项目ID
     * @param payStatusList 支付状态
     * @return 停车场总收入
     */
    PayOrderDto selectParkingOrderCountByMonthAndStatus(@Param("year") Integer year,
                                                        @Param("month") Integer month,
                                                        @Param("parkId") Long parkId,
                                                        @Param("payStatusList") List<String> payStatusList);

    /**
     * 按年月统计停车场总收入
     *
     * @param year       年
     * @param month      月
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param deptId     服务商ID
     * @param parkInfoId 项目ID
     * @return 停车场总收入
     */
    PayOrderDto selectParkingOrderCountByMonth(@Param("year") Integer year,
                                               @Param("month") Integer month,
                                               @Param("province") Integer province,
                                               @Param("city") Integer city,
                                               @Param("district") Integer district,
                                               @Param("deptId") Long deptId,
                                               @Param("parkInfoId") Long parkInfoId);

    /**
     * 统计停车场收入排行榜
     *
     * @param limit      取前几条
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param deptId     服务商ID
     * @param parkInfoId 项目ID
     * @return 停车场收入排行榜
     */
    List<PayOrderDto> selectParkingRevenueRanking(@Param("limit") Integer limit,
                                                  @Param("province") Integer province,
                                                  @Param("city") Integer city,
                                                  @Param("district") Integer district,
                                                  @Param("deptId") Long deptId,
                                                  @Param("parkInfoId") Long parkInfoId);

    /**
     * 查询年度总金额
     *
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param deptId     服务商ID
     * @param parkInfoId 项目ID
     * @return 年度总金额
     */
    BigDecimal selectTotalAnnualAmount(@Param("province") Integer province,
                                       @Param("city") Integer city,
                                       @Param("district") Integer district,
                                       @Param("deptId") Long deptId,
                                       @Param("parkInfoId") Long parkInfoId);

    /**
     * 统计支付方式分析（按日）
     *
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param parkInfoId 项目ID
     * @return /
     */
    PayOrderDto selectPaymentMethodOnDay(@Param("province") Integer province,
                                         @Param("city") Integer city,
                                         @Param("district") Integer district,
                                         @Param("parkInfoId") Long parkInfoId);

    /**
     * 统计支付方式分析（按月）
     *
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param parkInfoId 项目ID
     * @return /
     */
    PayOrderDto selectPaymentMethodOnMonth(@Param("province") Integer province,
                                           @Param("city") Integer city,
                                           @Param("district") Integer district,
                                           @Param("parkInfoId") Long parkInfoId);

    /**
     * 统计支付方式分析（按年）
     *
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param parkInfoId 项目ID
     * @return /
     */
    PayOrderDto selectPaymentMethodOnYear(@Param("province") Integer province,
                                          @Param("city") Integer city,
                                          @Param("district") Integer district,
                                          @Param("parkInfoId") Long parkInfoId);

    /**
     * 统计支付方式分析（某个时间段内的）
     *
     * @param startTime  开始时间
     * @param endTime    结束时间
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param deptId     服务商ID
     * @param parkInfoId 项目ID
     * @return /
     */
    PayOrderDto selectPaymentMethodOnThreeDay(@Param("startTime") String startTime,
                                              @Param("endTime") String endTime,
                                              @Param("province") Integer province,
                                              @Param("city") Integer city,
                                              @Param("district") Integer district,
                                              @Param("deptId") Long deptId,
                                              @Param("parkInfoId") Long parkInfoId);

    /**
     * 统计停车时常
     *
     * @param startTime  开始时间
     * @param endTime    结束时间
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param deptId     服务商ID
     * @param parkInfoId 项目ID
     * @return /
     */
    PayOrderDto selectParkingDuration(@Param("startTime") String startTime,
                                      @Param("endTime") String endTime,
                                      @Param("province") Integer province,
                                      @Param("city") Integer city,
                                      @Param("district") Integer district,
                                      @Param("deptId") Long deptId,
                                      @Param("parkInfoId") Long parkInfoId);

    /**
     * 统计某个区域内的今日支付方式
     *
     * @param province   省编码
     * @param city       市编码
     * @param district   区县编码
     * @param deptId     服务商ID
     * @param parkInfoId 项目ID
     * @return 今日支付方式统计
     */
    PayOrderDto selectPaymentMethodToday(@Param("province") Integer province,
                                         @Param("city") Integer city,
                                         @Param("district") Integer district,
                                         @Param("deptId") Long deptId,
                                         @Param("parkInfoId") Long parkInfoId);

    /**
     * 分页查询支付记录列表
     *
     * @param page            分页条件
     * @param payOrderRequest 查询条件
     * @return 查询结果
     */
    IPage<PayOrderVo> selectPageList(@Param("page") Page<PayOrderVo> page,
                                     @Param("payOrderRequest") PayOrderRequest payOrderRequest);

    /**
     * 根据停车流水号查询支付记录
     *
     * @param parkId        parkId
     * @param parkingSerial 停车流水号
     * @return 支付记录
     */
    List<PayOrderDto> selectPayOrderByParkingSerial(@Param("parkId") Long parkId,
                                                    @Param("parkingSerial") String parkingSerial);

    /**
     * 查询支付记录列表
     *
     * @param payOrder 支付记录
     * @return 支付记录集合
     */
    List<PayOrder> selectPayOrderList(PayOrder payOrder);

    /**
     * 根据值班员ID获取对应的统计信息
     *
     * @param parkId       车场ID
     * @param clientUserId 值班员ID
     * @param payTypeList  支付方式
     * @param beginTime    开始时间
     * @param endTime      结束时间
     * @return 统计信息
     */
    PayOrderVo selectStatisticsInfoByClientUserId(@Param("parkId") Long parkId,
                                                  @Param("clientUserId") Long clientUserId,
                                                  @Param("payTypeList") List<String> payTypeList,
                                                  @Param("beginTime") String beginTime,
                                                  @Param("endTime") String endTime);

    /**
     * 根据岗亭用户ID更新现金已结算金额
     *
     * @param clientUserId 岗亭用户ID
     */
    void updateCashSettlementFeeByClientUserId(@Param("clientUserId") Long clientUserId);


    /**
     * 统计电子支付金额
     *
     * @param parkId
     * @return java.lang.Long
     * @author shd
     * @date 2021/11/4 10:42
     */
    Double selectElectronicStatistic(Long parkId);

    /**
     * 统计现金收费金额
     *
     * @param parkId
     * @return java.lang.Long
     * @author shd
     * @date 2021/11/4 10:42
     */
    Double selectCashStatistic(Long parkId);

    /**
     * 统计未收金额
     *
     * @param parkId
     * @return java.lang.Long
     * @author shd
     * @date 2021/11/4 10:42
     */
    Double selectWaitStatistic(Long parkId);

    /**
     * 统计免费金额
     *
     * @param parkId
     * @return java.lang.Long
     * @author shd
     * @date 2021/11/4 10:42
     */
    Double selectFreeStatistic(Long parkId);

    /**
     * 统计现金收费金额
     *
     * @param parkId 项目id
     * @param userId 管理员用户id
     * @return java.lang.Long
     * @author shd
     * @date 2021/11/4 10:42
     */
    Double selectCashStatisticByUserId(@Param("parkId") Long parkId, @Param("userId") Long userId);

    /**
     * 统计免费金额
     *
     * @param parkId
     * @param userId 管理员用户id
     * @return java.lang.Double
     * @author shd
     * @date 2021/11/9 10:00
     */
    Double selectFreeStatisticByUserId(@Param("parkId") Long parkId, @Param("userId") Long userId);

    /**
     * 按支付类型选择统计信息
     *
     * @param payOrderRequest 支付记录请求对象
     * @return 统计信息
     */
    PayOrderVo selectStatisticalInfoByPayType(@Param("payOrderRequest") PayOrderRequest payOrderRequest);

    /**
     * 获取未收费金额信息
     *
     * @param parkId    车场ID
     * @param userId    岗亭值班员ID
     * @param beginTime 开始时间
     * @param endTime   结束时间
     * @return 未收费金额
     */
    BigDecimal selectNoPayFee(@Param("parkId") Long parkId,
                              @Param("userId") Integer userId,
                              @Param("beginTime") String beginTime,
                              @Param("endTime") String endTime);

    /**
     * 根据支付类型和岗亭用户信息查询支付列表
     *
     * @param page         分页参数
     * @param clientUserId 岗亭用户id
     * @param plate        车牌号
     * @param payType      支付类型
     * @param beginTime    开始时间
     * @param endTime      结束时间
     * @return 支付记录列表
     */
    IPage<PayOrderVo> selectPageListByPayType(@Param("page") Page<PayOrderVo> page,
                                              @Param("clientUserId") Long clientUserId,
                                              @Param("plate") String plate,
                                              @Param("payType") String payType,
                                              @Param("beginTime") String beginTime,
                                              @Param("endTime") String endTime);

    List<PayOrderVo> selectPageListByPayType(@Param("clientUserId") Long clientUserId,
                                             @Param("plate") String plate,
                                             @Param("payType") String payType,
                                             @Param("beginTime") String beginTime,
                                             @Param("endTime") String endTime);

    /**
     * 获取免费金额信息
     *
     * @param parkId    车场ID
     * @param userId    岗亭用户ID
     * @param beginTime 开始时间
     * @param endTime   结束时间
     * @return 免费金额
     */
    BigDecimal selectFreeFee(@Param("parkId") Long parkId,
                             @Param("userId") Integer userId,
                             @Param("beginTime") String beginTime,
                             @Param("endTime") String endTime);

    /**
     * 根据查询条件分页查询未收费列表
     *
     * @param page         分页参数
     * @param clientUserId 岗亭用户id
     * @param plate        车牌号
     * @param beginTime    开始时间
     * @param endTime      结束时间
     * @return 未收费列表
     */
    IPage<PayOrderVo> selectPageNoChargeList(@Param("page") Page<PayOrderVo> page,
                                             @Param("clientUserId") Long clientUserId,
                                             @Param("plate") String plate,
                                             @Param("beginTime") String beginTime,
                                             @Param("endTime") String endTime);


    List<PayOrderVo> selectPageNoChargeList(@Param("clientUserId") Long clientUserId,
                                            @Param("plate") String plate,
                                            @Param("beginTime") String beginTime,
                                            @Param("endTime") String endTime);

    /**
     * 根据车场ID统计当前车场的收入，按日去统计，统计所有的日期
     *
     * @param parkId 车场ID
     * @return 统计结果
     */
    List<ParkStatisticsIncome> selectStatisticsIncomeByDay(@Param("parkId") Long parkId);

    /**
     * 根据车场ID统计当前车场的收入，统计指定日期
     *
     * @param day    指定日期 yyyy-MM-dd
     * @param parkId 车场ID
     * @return 统计结果
     */
    ParkStatisticsIncome selectStatisticsIncomeByAppointDay(@Param("day") String day,
                                                            @Param("parkId") Long parkId);

    /**
     * 统计车场某段时间内的总收入
     *
     * @param parkId     车场id
     * @param statusList 支付状态列表
     * @param starDate   开始时间
     * @param endDate    结束时间
     * @return 金额
     */
    long getTotalRevenue(@Param("parkId") Long parkId,
                         @Param("statusList") List<String> statusList,
                         @Param("starDate") Date starDate,
                         @Param("endDate") Date endDate);

    /**
     * 根据支支付状态、统计车场某个时间段内的收入
     *
     * @param parkId     车场ID
     * @param statusList 支付状态
     * @param starDate   开始时间
     * @param endDate    结束时间
     * @return 统计结果
     */
    PayOrderDto getRevenue(@Param("parkId") Long parkId,
                           @Param("statusList") List<String> statusList,
                           @Param("starDate") Date starDate,
                           @Param("endDate") Date endDate);

    /**
     * 按年月统计停车场的支付方式
     *
     * @param year   年
     * @param month  月份
     * @param parkId 项目ID
     * @return 统计结果
     */
    PayOrderDto selectPayTypeCountByMonth(@Param("year") Integer year,
                                          @Param("month") Integer month,
                                          @Param("parkId") Long parkId);

    /**
     * 根据查询条件
     *
     * @param payOrderRequest
     * @return
     */
    Integer selectPayOderCount(@Param("payOrderRequest") PayOrderRequest payOrderRequest);

    /**
     * 根据查询条件查询总数
     *
     * @param payOrderRequest 支付记录查询条件
     * @return 总数
     */
    long selectIcbcPayOrderCount(PayOrderRequest payOrderRequest);

    /**
     * 根据条件分页查询工行支付记录
     *
     * @param page            分页参数
     * @param payOrderRequest 支付记录参数
     * @return 查询结果
     */
    IPage<PayOrderExportIcbcDto> selectPayOrderExportPage(@Param("page") Page<PayOrderExportIcbcDto> page,
                                                          @Param("payOrderRequest") PayOrderRequest payOrderRequest);
}
